From 4f357dbf956d2be0249e7f5aec7050ed05ba1b7b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 17 Jun 2010 15:41:12 +0100 Subject: [PATCH] application: Allow sub-classes to override the Window creation Sub-classes of GtkApplication might want to override the way an application window is created - for instance, to hook into GtkBuilder or to set up some basic UI or state. A new GtkApplication::create_window() virtual function is added to the GtkApplicationClass vtable, which returns the newly created GtkWindow. The gtk_application_create_window() function calls the vfunc and adds the returned window to the list of windows managed by the application instance. Calling gtk_application_add_window() will also set the default window, if one is not already set. This commit also removes a spurious g_object_ref_sink() on the newly created GtkWindow. --- gtk/gtk.symbols | 1 + gtk/gtkapplication.c | 79 ++++++++++++++++++++++++++++++++++++++------ gtk/gtkapplication.h | 12 ++++--- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index eba4e8ea89..feaba01c81 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -262,6 +262,7 @@ gtk_alignment_set_padding gtk_application_get_type G_GNUC_CONST gtk_application_new gtk_application_set_action_group +gtk_application_create_window gtk_application_get_window gtk_application_add_window gtk_application_run diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c index 56748f72e0..6b9b9bdfda 100644 --- a/gtk/gtkapplication.c +++ b/gtk/gtkapplication.c @@ -171,7 +171,13 @@ gtk_application_default_action (GtkApplication *application, gtk_action_activate (action); } } - + +static GtkWindow * +gtk_application_default_create_window (GtkApplication *application) +{ + return GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL)); +} + static void gtk_application_default_action_with_data (GApplication *application, const gchar *action_name, @@ -363,7 +369,12 @@ static gchar *default_title; * behaviour is to call gtk_application_quit(). * * If your application uses only a single toplevel window, you can - * use gtk_application_get_window(). + * use gtk_application_get_window(). If you are using a sub-class + * of #GtkApplication you should call gtk_application_create_window() + * to let the #GtkApplication instance create a #GtkWindow and add + * it to the list of toplevels of the application. You should call + * this function only to add #GtkWindows that you created + * directly using gtk_window_new(). * * Since: 3.0 */ @@ -371,13 +382,27 @@ void gtk_application_add_window (GtkApplication *app, GtkWindow *window) { - app->priv->windows = g_slist_prepend (app->priv->windows, window); + GtkApplicationPrivate *priv; + + g_return_if_fail (GTK_IS_APPLICATION (app)); + g_return_if_fail (GTK_IS_WINDOW (window)); + + priv = app->priv; + + if (g_slist_find (priv->windows, window) != NULL) + return; + + priv->windows = g_slist_prepend (priv->windows, window); + + if (priv->default_window == NULL) + priv->default_window = window; if (gtk_window_get_title (window) == NULL && default_title != NULL) gtk_window_set_title (window, default_title); g_signal_connect (window, "destroy", - G_CALLBACK (gtk_application_on_window_destroy), app); + G_CALLBACK (gtk_application_on_window_destroy), + app); } /** @@ -396,7 +421,8 @@ gtk_application_add_window (GtkApplication *app, * If your application has more than one toplevel window (e.g. an * single-document-interface application with multiple open documents), * or if you are constructing your toplevel windows yourself (e.g. using - * #GtkBuilder), use gtk_application_add_window() instead. + * #GtkBuilder), use gtk_application_create_window() or + * gtk_application_add_window() instead. * * Returns: (transfer none): The default #GtkWindow for this application * @@ -405,15 +431,45 @@ gtk_application_add_window (GtkApplication *app, GtkWindow * gtk_application_get_window (GtkApplication *app) { - if (app->priv->default_window != NULL) - return app->priv->default_window; + GtkApplicationPrivate *priv; + GtkWindow *window; + + g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL); + + priv = app->priv; + + if (priv->default_window != NULL) + return priv->default_window; + + return gtk_application_create_window (app); +} + +/** + * gtk_application_create_window: + * @app: a #GtkApplication + * + * Creates a new #GtkWindow for the application. + * + * This function calls the #GtkApplication::create_window() virtual function, + * which can be overridden by sub-classes, for instance to use #GtkBuilder to + * create the user interface. After creating a new #GtkWindow instance, it will + * be added to the list of toplevels associated to the application. + * + * Return value: (transfer none): the newly created application #GtkWindow + * + * Since: 3.0 + */ +GtkWindow * +gtk_application_create_window (GtkApplication *app) +{ + GtkWindow *window; - app->priv->default_window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL)); - g_object_ref_sink (app->priv->default_window); + g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL); - gtk_application_add_window (app, app->priv->default_window); + window = GTK_APPLICATION_GET_CLASS (app)->create_window (app); + gtk_application_add_window (app, window); - return app->priv->default_window; + return window; } /** @@ -578,6 +634,7 @@ gtk_application_class_init (GtkApplicationClass *klass) klass->quit = gtk_application_default_quit; klass->action = gtk_application_default_action; + klass->create_window = gtk_application_default_create_window; klass->activated = gtk_application_default_activated; diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h index dc01b422d9..2a808d77c6 100644 --- a/gtk/gtkapplication.h +++ b/gtk/gtkapplication.h @@ -66,11 +66,12 @@ struct _GtkApplicationClass GApplicationClass parent_class; /*< vfuncs >*/ - void (* activated) (GtkApplication *application, - GVariant *args); - void (* action) (GtkApplication *application, - const gchar *action_name); - gboolean (* quit) (GtkApplication *application); + GtkWindow *(* create_window) (GtkApplication *application); + void (* activated) (GtkApplication *application, + GVariant *args); + void (* action) (GtkApplication *application, + const gchar *action_name); + gboolean (* quit) (GtkApplication *application); /* Padding for future expansion */ @@ -92,6 +93,7 @@ GtkApplication* gtk_application_new (const gchar *appid, gchar ***argv); void gtk_application_set_action_group (GtkApplication *app, GtkActionGroup *group); +GtkWindow * gtk_application_create_window (GtkApplication *app); GtkWindow * gtk_application_get_window (GtkApplication *app); void gtk_application_add_window (GtkApplication *app, GtkWindow *window); -- 2.30.2